#ifndef SHADERMANAGER_H_
#define SHADERMANAGER_H_

#include "precom.h"
#include "SimpleShader.h"
#include <vector>

class ShaderManager
{
private:
	CGcontext cg_context;
	CGprofile cg_vertProfile, cg_fragProfile;
	size_t m_curShader;
protected:
	std::vector<CgShaderInterface*> m_shaders;
	std::vector<std::vector<boost::function<void(const fmath::vector3&)>>> m_vecParamTab;
	std::vector<std::vector<boost::function<void(float)>>> m_floatParamTab;

public:
	ShaderManager();
	~ShaderManager();

	bool InitShaders(HWND a_hWnd);
	void ClearShaders();
	void TurnShaderOn();
	void TurnShaderOff();
	
	inline void SetWorldViewProjMatrix()
	{
		m_shaders[m_curShader]->SetWorldViewProjMatrix();
	}
	inline void SetShaderVecData(const fmath::vector3& a_vec, size_t a_dataID)
	{
		if(a_dataID > ShaderExternalVecDataNum) return;
		if(m_vecParamTab[m_curShader][a_dataID])
			m_vecParamTab[m_curShader][a_dataID](a_vec);
	}
	inline void SetLightsPos(fmath::vector3* a_lightsTab, size_t a_lightsNum)
	{
		m_shaders[m_curShader]->SetLights(a_lightsTab, a_lightsNum);
	}
	inline void NextShader() 
	{ 
		if(++m_curShader >= m_shaders.size())
			m_curShader = 0;
	}
	inline void PrevShader() 
	{ 
		if(m_curShader == 0)
			m_curShader = m_shaders.size();
		--m_curShader;
	}
	inline void SignUpShader(CgShaderInterface* a_shader) 
	{
		m_shaders.push_back(a_shader);
		m_vecParamTab.push_back(a_shader->SignUpForVecInfo());
		m_floatParamTab.push_back(a_shader->SignUpForFloatInfo());
	}
};

#endif //SHADERMANAGER_H_